#include <time.h>
#include <sys/types.h>
#include <sys/stat.h>
#include <fcntl.h>
#include <stdarg.h>
#include <string.h>
#include <stdlib.h>
#include <stdio.h>
#include <unistd.h>
#include <errno.h>
#include "Log.h"

#define MAX_LOG_LENGTH 1024

Logger::Logger()
{
	fd = -1;
}

Logger::~Logger()
{
	if(fd >=0) {
		close(fd);
	}
	fd = -1;
}

Logger::Logger(const char *logFilePre, int m, int lev)
{
	fd = -1;
	logLevel = lev;
	memset(filePrefix, 0, sizeof(filePrefix));
	strncpy(filePrefix, logFilePre, sizeof(filePrefix)-1);
	mode = m;
}
void Logger::Judge_newday()
{
  switch(this->mode) {
		default:
            sprintf(filename, "./logs/%s", filePrefix);
            break;
        case DAILY_LOG:
			if(tm.tm_mday != otm.tm_mday)
			{
				sprintf(filename, "./logs/%s_%04d%02d%02d.log",  this->filePrefix, tm.tm_year+1900, tm.tm_mon+1, tm.tm_mday);
				close(fd);
			}
            break;
		case MONTHLY_LOG:
			if(tm.tm_mon != otm.tm_mon)
			{
				sprintf(filename,"./logs/%s_%04d%02d.log",this->filePrefix,tm.tm_year+1900,tm.tm_mon+1);
				close(fd);
			}
			break;
		case YEARLY_LOG:
			if(tm.tm_year != otm.tm_year)
			{
				sprintf(filename,"./logs/%s_%04d.log",this->filePrefix,tm.tm_year+1900);
				close(fd);
			}
			break;
  }

}

bool Logger::Log(const char *modName, int level, const char *fmt, ...) 
{
	if(level < logLevel)
	{
		return false;
	}
	int len;
	va_list ap;
	char *line;
	//int fd;
	//char filename[128];
	//struct tm otm;
	time_t t;
	static const char *levelStr[] = {"DEBUG", "INFO", "WARN", "ERROR"};
	
    t = time(NULL);
    localtime_r(&t, &tm);


     //根据日志记录模式，判断是否已是新的一天或新的一个月，若是，则需要根据情况关闭文件再创建新的文件
	Judge_newday();
	//先判断文件是否已打开，未打开则打开文件
    if(fd  == -1) 
	{
        //根据模式确定打开的文件名格式，追加模式打开
        if((fd = open(filename, O_CREAT|O_APPEND|O_WRONLY, 0666)) < 0) {
            perror("open");
            return false;
        }
    }
	line = (char *)malloc(MAX_LOG_LENGTH+1);
    len = snprintf(line, MAX_LOG_LENGTH,"[%04d-%02d-%02d %02d:%2d:%2d][%s][%s]:",tm.tm_year+1900, tm.tm_mon+1, tm.tm_mday, tm.tm_hour,tm.tm_min, tm.tm_sec, modName, levelStr[level]);

	if(line == NULL) {
		close(fd);
		return false;
	}

    va_start(ap, fmt);
	len = vsnprintf(line+len, MAX_LOG_LENGTH-len, fmt, ap);
	va_end( ap );


	write(fd, line, strlen(line));

	free(line);

	return true;
}

